package common.loader
{

	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.URLRequest;
	import flash.net.URLStream;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;

	import util.Logger;

	public class BaseLoader extends URLStream
	{
		public var info:Info;
		public var domain:ApplicationDomain;
		public var handler:Function;
		public var started:Boolean;
		public var finished:Boolean;

		private static var loaderQueue:Array;

		public static function init(max:uint):void
		{
			loaderQueue = new Array();

			for(var i:int = 0; i < max; i++)
			{
				loaderQueue.push(new BaseLoader());
			}
		}

		public static function add(info:Info, callback:Function):void
		{
			var loader:BaseLoader = loaderQueue.shift() as BaseLoader;
			loader.handler = callback;
			loader.start(info);
		}

		public function BaseLoader()
		{
			super();
			started = false;
			finished = true;
			addEventListener(Event.COMPLETE, completeHandler);
			addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
			addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityHandler);
		}

		public function start(target:Info):void
		{
			info = target;
			started = true;
			finished = false;
			super.load(new URLRequest(info.url));
		}

		protected function completeHandler(event:Event):void
		{
			started = false;
			finished = true;

			if(handler != null)
			{
				var byteArray:ByteArray = new ByteArray();
				(event.target as BaseLoader).readBytes(byteArray);
				info.raw = byteArray;
				handler(info);
			}
			loaderQueue.push(this);
		}

		private function errorHandler(event:IOErrorEvent):void
		{
			Logger.error(event.toString());
		}

		private function securityHandler(event:SecurityErrorEvent):void
		{
			Logger.error(event.toString());
		}
	}
}